package com.linkgie.galaxyframework.crypto;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

class AlgorithmMap implements AlgorithmCodec {

	private Map<String, Algorithm> nameCodes = new ConcurrentHashMap<String, Algorithm>();
	private Map<Short, Algorithm> codeNames = new ConcurrentHashMap<Short, Algorithm>();

	@Override
	public Algorithm getAlgorithm(String name) {
		return nameCodes.get(name);
	}

	@Override
	public Algorithm getAlgorithm(short code) {
		return codeNames.get(code);
	}
	
	public boolean contains(Algorithm algorithm) {
		return nameCodes.containsKey(algorithm.getName()) || codeNames.containsKey(algorithm.getCode());
	}

	public Collection<Algorithm> getAlgorithms() {
		return nameCodes.values();
	}

	public boolean isEmpty(){
		return codeNames.isEmpty();
	}

	/**
	 * 加入新的密码算法；
	 * <p>
	 * 如果密码算法的名称和编码存在冲突，则抛出 {@link CryptoException} 异常；
	 * 
	 * @param algorithms
	 */
	public void add(Collection<Algorithm> algorithms) {
		for (Algorithm algorithm : algorithms) {
			add(algorithm);
		}
	}

	/**
	 * 加入新的密码算法；
	 * <p>
	 * 如果密码算法的名称和编码存在冲突，则抛出 {@link CryptoException} 异常；
	 * 
	 * @param algorithms
	 */
	public void add(Algorithm algorithm) {
		Algorithm alg = nameCodes.get(algorithm.getName());
		if (alg != null) {
			throw new CryptoException("Algorithm name conflition! -- Algorithm named [" + alg.getName()
					+ "] already exist with code [" + alg.getCode() + "]!");
		}
		alg = codeNames.get(algorithm.getCode());
		if (alg != null) {
			throw new CryptoException("Algorithm code conflition! -- Algorithm coded [" + algorithm.getCode()
					+ "] already exist with name [" + alg.getName() + "]!");
		}
		nameCodes.put(algorithm.getName(), algorithm);
		codeNames.put(algorithm.getCode(), algorithm);
	}
}